"""
Test Skill Loader
"""

import tempfile
from pathlib import Path

import pytest

from mini_agent.tools.skill_loader import Skill, SkillLoader


def create_test_skill(skill_dir: Path, name: str, description: str, content: str):
    """Create a test skill"""
    skill_file = skill_dir / "SKILL.md"
    skill_content = f"""---
name: {name}
description: {description}
---

{content}
"""
    skill_file.write_text(skill_content, encoding="utf-8")


def test_load_valid_skill():
    """Test loading a valid skill"""
    with tempfile.TemporaryDirectory() as tmpdir:
        skill_dir = Path(tmpdir) / "test-skill"
        skill_dir.mkdir()

        create_test_skill(
            skill_dir,
            "test-skill",
            "A test skill",
            "This is a test skill content.",
        )

        loader = SkillLoader(tmpdir)
        skill = loader.load_skill(skill_dir / "SKILL.md")

        assert skill is not None
        assert skill.name == "test-skill"
        assert skill.description == "A test skill"
        assert "This is a test skill content" in skill.content


def test_load_skill_with_metadata():
    """Test loading a skill with metadata"""
    with tempfile.TemporaryDirectory() as tmpdir:
        skill_dir = Path(tmpdir) / "test-skill"
        skill_dir.mkdir()

        skill_file = skill_dir / "SKILL.md"
        skill_content = """---
name: test-skill
description: A test skill
license: MIT
allowed-tools:
  - read_file
  - write_file
metadata:
  author: Test Author
  version: "1.0"
---

Skill content here.
"""
        skill_file.write_text(skill_content, encoding="utf-8")

        loader = SkillLoader(tmpdir)
        skill = loader.load_skill(skill_file)

        assert skill is not None
        assert skill.name == "test-skill"
        assert skill.license == "MIT"
        assert skill.allowed_tools == ["read_file", "write_file"]
        assert skill.metadata["author"] == "Test Author"
        assert skill.metadata["version"] == "1.0"


def test_load_invalid_skill():
    """Test loading an invalid skill (missing frontmatter)"""
    with tempfile.TemporaryDirectory() as tmpdir:
        skill_dir = Path(tmpdir) / "invalid-skill"
        skill_dir.mkdir()

        skill_file = skill_dir / "SKILL.md"
        skill_file.write_text("No frontmatter here!", encoding="utf-8")

        loader = SkillLoader(tmpdir)
        skill = loader.load_skill(skill_file)

        assert skill is None


def test_discover_skills():
    """Test discovering multiple skills"""
    with tempfile.TemporaryDirectory() as tmpdir:
        # Create multiple skills
        for i in range(3):
            skill_dir = Path(tmpdir) / f"skill-{i}"
            skill_dir.mkdir()
            create_test_skill(
                skill_dir, f"skill-{i}", f"Test skill {i}", f"Content {i}"
            )

        loader = SkillLoader(tmpdir)
        skills = loader.discover_skills()

        assert len(skills) == 3
        assert len(loader.list_skills()) == 3


def test_get_skill():
    """Test getting a loaded skill"""
    with tempfile.TemporaryDirectory() as tmpdir:
        skill_dir = Path(tmpdir) / "test-skill"
        skill_dir.mkdir()
        create_test_skill(skill_dir, "test-skill", "Test", "Content")

        loader = SkillLoader(tmpdir)
        loader.discover_skills()

        skill = loader.get_skill("test-skill")
        assert skill is not None
        assert skill.name == "test-skill"

        # Test non-existent skill
        assert loader.get_skill("nonexistent") is None



def test_get_skills_metadata_prompt():
    """Test generating metadata-only prompt (Progressive Disclosure Level 1)"""
    with tempfile.TemporaryDirectory() as tmpdir:
        # Create test skills with different names to test categorization
        # Use longer content to simulate real skills
        long_content = """
# Detailed Skill Content

This is a comprehensive skill guide with lots of detailed instructions.

## Section 1
Here are detailed instructions for using this skill.

## Section 2
More detailed content and examples.

## Section 3
Even more content to make this realistic.
""" * 3  # Make it substantial

        skills_data = [
            ("pdf", "PDF manipulation toolkit", long_content),
            ("docx", "Document creation tool", long_content),
            ("canvas-design", "Canvas design tool", long_content),
        ]

        for name, desc, content in skills_data:
            skill_dir = Path(tmpdir) / name
            skill_dir.mkdir()
            create_test_skill(skill_dir, name, desc, content)

        loader = SkillLoader(tmpdir)
        loader.discover_skills()

        # Test metadata prompt generation
        metadata_prompt = loader.get_skills_metadata_prompt()

        # Should contain skill names and descriptions
        assert "pdf" in metadata_prompt
        assert "docx" in metadata_prompt
        assert "canvas-design" in metadata_prompt
        assert "PDF manipulation toolkit" in metadata_prompt
        assert "Document creation tool" in metadata_prompt

        # Should contain Progressive Disclosure explanation
        assert "Available Skills" in metadata_prompt

        # Should NOT contain full content (only metadata)
        assert "Detailed Skill Content" not in metadata_prompt
        assert "Section 1" not in metadata_prompt
        assert "Section 2" not in metadata_prompt


def test_nested_document_path_processing():
    """Test processing of nested document references (Level 3+)"""
    with tempfile.TemporaryDirectory() as tmpdir:
        skill_dir = Path(tmpdir) / "test-skill"
        skill_dir.mkdir()

        # Create nested documents
        (skill_dir / "reference.md").write_text("Reference content", encoding="utf-8")
        (skill_dir / "forms.md").write_text("Forms content", encoding="utf-8")

        # Create SKILL.md with nested references
        skill_content = """---
name: test-skill
description: Test skill with nested docs
---

For advanced features, see reference.md.
If you need forms, read forms.md and follow instructions.
"""
        (skill_dir / "SKILL.md").write_text(skill_content, encoding="utf-8")

        loader = SkillLoader(tmpdir)
        skill = loader.load_skill(skill_dir / "SKILL.md")

        assert skill is not None

        # Check that paths are converted to absolute and include instructions
        assert str(skill_dir / "reference.md") in skill.content
        assert str(skill_dir / "forms.md") in skill.content
        assert "use read_file" in skill.content.lower()


def test_script_path_processing():
    """Test processing of script paths in skills"""
    with tempfile.TemporaryDirectory() as tmpdir:
        skill_dir = Path(tmpdir) / "test-skill"
        skill_dir.mkdir()

        # Create scripts directory
        scripts_dir = skill_dir / "scripts"
        scripts_dir.mkdir()
        (scripts_dir / "test_script.py").write_text("# Python script", encoding="utf-8")

        # Create SKILL.md with script reference
        skill_content = """---
name: test-skill
description: Test skill with scripts
---

Run the script: python scripts/test_script.py
"""
        (skill_dir / "SKILL.md").write_text(skill_content, encoding="utf-8")

        loader = SkillLoader(tmpdir)
        skill = loader.load_skill(skill_dir / "SKILL.md")

        assert skill is not None

        # Check that script path is converted to absolute
        assert str(skill_dir / "scripts" / "test_script.py") in skill.content
